package com.tanhua.dubbo.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.mongodb.client.result.UpdateResult;
import com.tanhua.dubbo.utils.IdWorker;
import com.tanhua.dubbo.utils.TimeLineService;
import com.tanhua.model.enums.CommentType;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.MovementTimeLine;
import com.tanhua.model.mongo.Video;
import com.tanhua.model.vo.MovementsVO;
import com.tanhua.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Xiao
 * @date 2021/10/25
 */
@DubboService
public class MovementApiImpl implements MovementApi {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private TimeLineService timeLineService;

    @Override
    public String publish(Movement movement) {
        try {
            //保存动态详情
            Long pid = idWorker.getNextId("movement");
            movement.setPid(pid);
            movement.setCreated(System.currentTimeMillis());
            //movement.setId(ObjectId.get());
            mongoTemplate.save(movement);

            /*//查询当前用户的好友数据
            Query query = Query.query(Criteria.where("userId").is(movement.getUserId()));
            List<Friend> friends = mongoTemplate.find(query, Friend.class);
            Thread.sleep(10000L);
            //循环好友数据，构建时间线数据并保存
            List<MovementTimeLine> movementTimeLines = new ArrayList<>();
            for (Friend friend : friends) {
                MovementTimeLine movementTimeLine = new MovementTimeLine();
                movementTimeLine.setMovementId(movement.getId());
                movementTimeLine.setUserId(friend.getUserId());
                movementTimeLine.setFriendId(friend.getFriendId());
                movementTimeLine.setCreated(System.currentTimeMillis());
//                mongoTemplate.save(movementTimeLine);
                movementTimeLines.add(movementTimeLine);
            }
            mongoTemplate.insertAll(movementTimeLines);*/

            timeLineService.saveTimeLine(movement.getUserId(), movement.getId());
            return movement.getId().toHexString();
        } catch (Exception e) {
            //忽略事物处理
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public PageResult selectByUserId(Integer page, Integer pagesize, Long userId) {
        Criteria criteria = Criteria.where("userId").is(userId).and("state").is(1);
        Query query = Query.query(criteria);
        Long counts = mongoTemplate.count(query, Movement.class);
        Long skip = Long.valueOf((page - 1) * pagesize);
        query.skip(skip).limit(pagesize).with(Sort.by(Sort.Order.desc("created")));
        List<Movement> movements = mongoTemplate.find(query, Movement.class);
        return new PageResult(page, pagesize, Integer.parseInt(String.valueOf(counts)), movements);
    }

    @Override
    public PageResult findFriendMovements(Integer page, Integer pagesize, Long friendId) {
        //根据userId从时间线表查出动态id
        Query timeQuery = Query.query(Criteria.where("friendId").is(friendId));
        List<MovementTimeLine> movementTimeLines = mongoTemplate.find(timeQuery, MovementTimeLine.class);
        List<ObjectId> ids = CollUtil.getFieldValues(movementTimeLines, "movementId", ObjectId.class);
        //根据动态id从动态表查出动态详情
        Query movementQuery = Query.query(Criteria.where("id").in(ids).and("state").is(1));
        Long counts = mongoTemplate.count(movementQuery, Movement.class);
        Long skip = Long.valueOf((page - 1) * pagesize);
        movementQuery.skip(skip).limit(pagesize).with(Sort.by(Sort.Order.desc("created")));
        List<Movement> movements = mongoTemplate.find(movementQuery, Movement.class);
        return new PageResult(page, pagesize, Integer.parseInt(String.valueOf(counts)), movements);
    }

    /**
     * 随机获取Movement数据
     * @param pagesize
     * @return
     */
    @Override
    public List<Movement> getRandomMovements(Integer pagesize) {
        //创建统计对象，设置统计参数
        TypedAggregation<Movement> aggregation = Aggregation.newAggregation(
                Movement.class,
                Aggregation.sample(pagesize));
        //调用mongoTemplate.aggregate()方法进行统计
        AggregationResults<Movement> aggregate = mongoTemplate.aggregate(aggregation, Movement.class);
        //获取统计结果
        return aggregate.getMappedResults();
    }

    @Override
    public List<Movement> findRecommendMovements(List<Long> pids) {
        Query query = Query.query(Criteria.where("pid").in(pids).and("state").is(1));
        return mongoTemplate.find(query, Movement.class);
    }

    @Override
    public Movement findById(String movementId) {
        return mongoTemplate.findById(movementId, Movement.class);
    }

    @Override
    public List<Comment> getList(Long userId, CommentType commentType, Integer page, Integer pagesize) {
        Criteria criteria = Criteria
                .where("publishUserId").is(userId)
                .and("commentType").is(commentType.getType());
        Long skip = Long.valueOf((page - 1) * pagesize);
        Query query = Query.query(criteria)
                .skip(skip)
                .limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        return mongoTemplate.find(query, Comment.class);
    }

    @Override
    public PageResult getMessages(Integer page, Integer pagesize, Long uid, String state) {
        Criteria criteria = new Criteria();
        if (ObjectUtil.isNotEmpty(uid)) {
            criteria.and("userId").is(uid);
        }
        if (ObjectUtil.isNotEmpty(state)) {
            criteria.and("state").is(Integer.parseInt(state));
        }
        Long counts = mongoTemplate.count(Query.query(criteria), Movement.class);
        Long skip = (long) (page - 1) * pagesize;
        Query query = Query.query(criteria)
                .skip(skip).limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        List<Movement> movements = mongoTemplate.find(query, Movement.class);
        return new PageResult(page, pagesize, Integer.parseInt(counts.toString()), movements);
    }

    @Override
    public String updateState(List<ObjectId> movementIds, Integer state) {
        Query query = Query.query(Criteria.where("id").in(movementIds));
        Update update = Update.update("state", state);
        mongoTemplate.updateMulti(query, update, Movement.class);
        return "已审核！";
    }
}
